<?php

class Bcms_Resource 
{
	/**
	 * Coleccion de recursos
	 * 
	 * @var array Coleccion Bcms_Resource_Model
	 */
	protected $_resource = null;
	
	protected $_resourceMeta = array();
	
	/**
	 * Adaptador de Base de datos
	 * 
	 * @var Zend_Db_Adapter_Abstract
	 */
	protected $_dbAdapter;
	
	/**
	 * 
	 */
	protected $_options = array(
		'core_model' => 'bcms_core'
	);

	/**
	 * @var Zend_Db_Table
	 */
	protected $_coreModel = null;
	
	protected $_formConfig = array();
	
	protected $_fields = null;
	
	protected $_form = array();
	
	protected $_formOptions = array(
		'decorators'	=>	array(
			'FormElements',
			array( 'HtmlTag', array('tag' => 'table') ),
			'Form'
		),
		'elementDecorators'	=>	array(
			'ViewHelper',
			'Errors',
			array( array('td'=>'HtmlTag'), array('tag' => 'td') ),
			array( 'Label', array('tag' => 'td') ),
			array( array('tr'=>'HtmlTag'), array('tag' => 'tr') ) 
		)
	);
	
	/**
	 * Instancia de la clase
	 * 
	 * @var Bcms_Resource
	 */
	protected static $_instance;

	public function __construct( $name = false, $options = false )
	{
		$this->_dbAdapter = Zend_Db_Table_Abstract::getDefaultAdapter();

		if ( $options ) {
			$this->setOptions($options);
		}

		if ( !$name ) {
			return $this;
		}

		$this->setResource( $name );
	}
	
	public function setOptions( $options )
	{
		if ( $options instanceof Zend_Config ) {
			$options = $options->toArray();
		} elseif ( is_string($options) ) {
			$options = array();
		}

		foreach ( $options as $k => $v ) {
			$this->_options[$k] = $v;
		}
		
		return $this;
	}
	
	public function setFormOptions( $options = array() )
	{
		if ( null === $this->_formOptions ) {
			$this->_formOptions = $options;
		} else {
			$this->_formOptions = array_merge( $this->_formOptions, $options );
		}
	}

	/**
	 * Obtener el recurso requerido
	 * 
	 * @param int|string Identificador del recurso, ID o nombre
	 * @trow Bcms_Resource_Exception 
	 */
	public function setResource( $resource )
	{
		if ( is_int( $resource ) ) {
			$this->_getResourceById( $resource );
		} elseif ( is_string( $resource ) ) {
			if ( is_numeric( $resource ) ) {
				$this->_getResourceById( $resource );
			} else {
				$this->_getResourceByName( $resource );
			}
		} else {
			throw new Bcms_Resource_Exception('Identificador de recurso invalido');
		}
	}

	/**
	 * Obtiene el recurso del recurso
	 * 
	 * @return Bcms_Resource_Model
	 */
	public function getResource()
	{
		return $this->_resource;
	}
	
	public function getResourceMeta( $field = false, $type = 'elements' )
	{
		if( is_array( $this->_resourceMeta ) ) {
			if ( $type ) {
				if ( array_key_exists( $type, $this->_resourceMeta ) ) {
					if ( $field ) {
						if( array_key_exists( $field, $this->_resourceMeta[$type] ) ) {
							return $this->_resourceMeta[$type][$field];
						} else {
							return array();
						}
					} else {
						return $this->_resourceMeta[$type];
					}
				} else {
					return array();
				}
			} else {
				return $this->_resourceMeta;
			}
		}

		return array();
	}
	
	protected function _getResourceById( $id )
	{
		$coreModel = $this->_getCoreModel();

		$where = $coreModel->getAdapter()->quoteInto('id = ?', $id);
		$row = $coreModel->fetchRow( $where );
		
		$this->_resource = new Bcms_Resource_Model( $row->table_name );
		$this->_resourceMeta = unserialize( $row->meta_data );
	}
	
	protected function _getResourceByName( $name )
	{
		$coreModel = $this->_getCoreModel();

		$where = $coreModel->getAdapter()->quoteInto( 'table_name = ?', $name );
		$row = $coreModel->fetchRow( $where );

		$this->_resource = new Bcms_Resource_Model( $name );
		$this->_resourceMeta = unserialize( $row->meta_data );
	}

	/**
	 * Obtener el model base con los recursos
	 * 
	 * @return Zend_Db_Table
	 */
	protected function _getCoreModel()
	{
		if ( null === $this->_coreModel ) {
			$this->_coreModel = new Zend_Db_Table( $this->_options['core_model'] );
		}
		
		return $this->_coreModel;
	}
	
	public function getResources()
	{
		return $this->_resources;
	}
	
	public function getFields()
	{
		if( null === $this->_fields ) {
			$resource = $this->getResource();

			$this->_fields = $resource->getFields();
		}
		
		return $this->_fields;
	}
	
	public function getComponents()
	{
		foreach ( $this->getFields() as $field ) {
			$component = new Bcms_Resource_Component( $field );
			$metaData = $this->getResourceMeta( $field['COLUMN_NAME'] );
			if( isset( $metaData ) ){
				$component->setOptions( $metaData );
			}
			$this->_components['elements'][$field['COLUMN_NAME']] = $component->getOptions();
		}
		
		return $this->_components;
	}
	
	/**
	 * Obtiene el formulario del recurso
	 * 
	 * @return Zend_Form
	 */
	public function getForm()
	{
		$this->_options = array_merge( $this->_formOptions, $this->getComponents() );
		$config = new Zend_Config( $this->_options );
		$form = new Zend_Form( $config );
		
		return $form;
	}

	/**
	 * Obtiene el modelo base con los recursos
	 * 
	 * @return Zend_Db_Table
	 */
	public function getCoreModel()
	{
		return $this->_getCoreModel();
	}
	
	/**
	 * Singleton Instance
	 * 
	 * @return Bcms_Resource
	 */
	public static function getInstance($name = array())
	{
		if (null === self::$_instance) {
			if ( is_string( $name )) {
				$options = array(
					'core_model' => $name
				);
			} elseif ( $name instanceof Zend_Config ) {
				$options = $name->toArray();
			} elseif ( is_array($name) ) {
				$options = $name;
			} else {
				$options = array();
			}

            self::$_instance = new self( $options );
        }

        return self::$_instance;
	}	
}